﻿module Lab3_5

let rectangle a b y h =
  let xs = [ for x in a..h..b -> x ]
  h * (List.sum [ for i in 1..(xs.Length-1) -> y ((xs.[i-1] + xs.[i]) / 2.0) ])

let trapeze a b y h =
  let xs = [ for x in a..h..b -> x ]
  let ys = List.map y xs
  let y1, yN = ys.[0] / 2.0, ys.[ys.Length-1] / 2.0
  h * ((List.sum ys) - y1 - yN)

let simpsonPart y lastIndex index x =
  y(x) * 
  match index with
  | 0 -> 1.0
  | _ when index = lastIndex -> 1.0
  | _ when index % 2 = 1 -> 4.0
  | _ -> 2.0 

let simpson a b y h =
  if a = b then
    0.0
  else
    let xs = [ for x in a..h..b -> x ]
    let helper = (simpsonPart y (xs.Length-1))
    let ys = List.mapi helper xs
    (h / 3.0) * List.sum ys

let rrr f fr k p =
  f + (f - fr) / (k ** p - 1.0)

let RRR a b y h1 h2 p f =
  let selectedMethod = f a b y
  let f2h, fh = selectedMethod h1, selectedMethod h2
  rrr f2h fh (h2 / h1) p

let lab = 
  printfn "Lab 3.5"
  let y x = (x ** 2.0) / (625.0 - x ** 4.0)
  let a, b = 0.0, 4.0
  let h1, h2 = 1.0, 0.5
  let rightAnswer = 0.0423871
  let error answer = abs (answer - rightAnswer)
  printfn "Steps: h1 = %f, h2 = %f" h1 h2
  printfn "Rectangle h1: %f" (rectangle a b y h1)
  printfn "Rectangle h2: %f" (rectangle a b y h2)
  printfn "Trapeze h1: %f" (trapeze a b y h1)
  printfn "Trapeze h2: %f" (trapeze a b y h2)
  printfn "Simpson h1: %f" (simpson a b y h1)
  printfn "Simpson h2: %f" (simpson a b y h2)
  printfn "-------\nClarify with RRR:"
  let clarify = RRR a b y h1 h2 
  printfn "\tRectangle: %f" (error (clarify 2.0 rectangle))
  printfn "\tTrapeze: %f" (error (clarify 2.0 trapeze))
  printfn "\tSimpson: %f" (error (clarify 4.0 simpson))
  printfn "======="